package com.neolix.udpserver;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import org.greenrobot.eventbus.EventBus;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Objects;

public class UdpService extends Service {
    private static final String TAG = "UdpService";
    private static final int PORT_SERVER = 9090;
    private DatagramSocket socket;
    private Thread udpRecvThread;
    private HashMap<ClientInfo, Long> clientInfoHashMap = new HashMap();
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "UdpService:onCreate");
        updServer();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "UdpService:onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "UdpService:onDestroy");
        if (socket != null) {
            socket.close();
            socket = null;
            udpRecvThread.interrupt();
        }
    }

    private void updServer() {
        try {

            socket = new DatagramSocket(null);
            socket.setReuseAddress(true);
            socket.bind(new InetSocketAddress(PORT_SERVER));
            udpRecvThread = new Thread(new UdpRecHandler(socket), "thread_udp_recv");
            udpRecvThread.start();
        }catch (Exception e) {
            Log.d(TAG, "创建udpsocket出现了错误:" + e.toString());
        }
    }

    private class UdpRecHandler implements Runnable {
        private DatagramSocket socket;
        private UdpRecHandler(DatagramSocket socket){
            this.socket = socket;
        }
        @Override
        public void run() {

            while (!Thread.currentThread().isInterrupted()) {
                Log.d(TAG, "开始接收数据");
                try {
                    byte[] data = new byte[1024];// 创建字节数组，指定接收的数据包的大小
                    DatagramPacket packet = new DatagramPacket(data, data.length);
                    socket.receive(packet);
                    //读取成功
                    InetAddress address = packet.getAddress();
                    int port = packet.getPort();
                    ClientInfo clientInfo = new ClientInfo(address, port);

                    String info = new String(data, 0, packet.getLength());
                    UdpMsg udpMsg = FastJsonUtils.jsonToObject(info, UdpMsg.class);
                    boolean isLegalPack = false;
                    Log.d(TAG, String.format("接收了客户端：%s:%d 数据为：%s",address.getHostName(), port, info));
                    ClientInfo clientInfoCache = findClientInfo(clientInfo);
                    if (clientInfoCache == null) {
                        //没有 告知有一个客户端上线了
                        EventMessageWrap eventOnlineMessageWrap = new EventMessageWrap();
                        eventOnlineMessageWrap.setTypeMsg(EventMessageWrap.TYPE_MSG_GO_ONLINE);
                        eventOnlineMessageWrap.setData(clientInfo);
                        noticeMsg(eventOnlineMessageWrap);
                        isLegalPack = true;
                        Log.d(TAG, "客户端上线了");
                    } else {
                        long time = clientInfoCache.getTime();
                        long current = udpMsg.getTs();
                        isLegalPack = current > time;
                    }

                    if (udpMsg != null && isLegalPack) {
                        //同步时间错
                        Log.d(TAG, String.format("接收了客户端1：%s:%d 数据为：%s",address.getHostName(), port, info));
                        clientInfo.setTime(udpMsg.getTs());
                        //发送通知
                        EventMessageWrap eventSendMessageWrap = new EventMessageWrap();
                        eventSendMessageWrap.setTypeMsg(EventMessageWrap.TYPE_MSG_SEND_MSG);
                        eventSendMessageWrap.setData(udpMsg);
                        noticeMsg(eventSendMessageWrap);
                        //更新客户端信息
                        if (clientInfoCache != null) {
                            clientInfoHashMap.remove(clientInfoCache);
                        }
                        clientInfoHashMap.put(clientInfo, System.currentTimeMillis());
                    }


                }catch (Exception e){
                    Log.d(TAG, "UdpRecHandler 出现了异常,退出了循环");
                }
            }
        }
    }

    private ClientInfo findClientInfo(ClientInfo c) {
        if (c == null) {
            return null;
        }
        Iterator<ClientInfo> iter = clientInfoHashMap.keySet().iterator();
        while (iter.hasNext()) {
            ClientInfo clientInfo = iter.next();
            if (c.equals(clientInfo)) {
                return clientInfo;
            }
        }
        return  null;
    }
    private void noticeMsg(EventMessageWrap eventMessageWrap) {
        EventBus.getDefault().post(eventMessageWrap);
    }

}
